package com.bestcem.xm.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.enums.AuthErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.common.core.uitls.DateUtil;
import com.bestcem.xm.user.config.properties.SettingProperties;
import com.bestcem.xm.user.constant.CommonConstant;
import com.bestcem.xm.user.constant.SmsConstant;
import com.bestcem.xm.user.constant.UserOutterCacheKeyConstant;
import com.bestcem.xm.user.entity.pojo.UserDO;
import com.bestcem.xm.user.enums.*;
import com.bestcem.xm.user.grpc.client.*;
import com.bestcem.xm.user.grpc.client.dto.MiniProgramOrderDTO;
import com.bestcem.xm.user.grpc.client.dto.OrderDTO;
import com.bestcem.xm.user.grpc.client.dto.PackageDTO;
import com.bestcem.xm.user.grpc.client.dto.UserWxDataCacheDTO;
import com.bestcem.xm.user.mq.message.user.SmsMessage;
import com.bestcem.xm.user.service.*;
import com.bestcem.xm.user.service.dto.order.*;
import com.bestcem.xm.user.service.dto.role.UserRoleDTO;
import com.bestcem.xm.user.service.dto.user.OrganizationDTO;
import com.bestcem.xm.user.service.dto.user.UserDTO;
import com.bestcem.xm.user.service.dto.user.WxMackOrderDTO;
import com.bestcem.xm.user.util.UserAsyncUtil;
import com.bestcem.xm.user.util.business.DataBaseUtil;
import com.bestcem.xm.user.util.business.StringFormatUtil;
import com.bestcem.xm.user.util.business.UserUtil;
import com.bestcem.xm.wallet.enums.OmEmailType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 订单实现类
 *
 * @author Linzhijian <zhijian.lin@idiaoyan.com>
 * @version v1.0
 * @date 2022/5/05 13:56
 */

@Slf4j
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private SettingProperties settingProperties;

    @Resource
    private OrganizationService organizationService;

    @Resource
    private PackageGrpcService packageGrpcService;

    @Resource
    private UserWalletGrpcService userWalletGrpcService;

    @Resource
    private UserService userService;

    @Resource
    private UserPaymentGrpcService userPaymentGrpcService;

    @Resource
    private RoleService roleService;

    @Resource
    private UserUserRoleService userUserRoleService;

    @Resource
    private UserBusinessService userBusinessService;

    @Resource
    private MailService mailService;

    @Resource
    private UserAsyncUtil userAsyncUtil;

    @Resource
    private UserUtil userUtil;

    @Resource
    private UserSmsService userSmsService;

    //@Resource
    //private UserMessageSender userMessageSender;

    @Resource
    private UserWechatGrpcService userWechatGrpcService;

    @Autowired
    private OmUserGrpcService omUserGrpcService;


    @Resource(name = "orderUpgradeExecutor")
    private ScheduledThreadPoolExecutor executor;

    @Override
    public ServiceResult<String> offlineConfirmOrder(String orderId) {
        // 通过企业钱包grpc获取orderInfo,判断支付状态
        OrderDTO orderInfo = userPaymentGrpcService.getOrderStatus(orderId);
        if (Objects.isNull(orderInfo) || !OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType().equals(orderInfo.getType())
                || !PaymentMethodEnum.PAYMENT_METHOD_OFFLINE.getType().equals(orderInfo.getPayMethod())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, String.format("orderId:%s不正确", orderId));
        }

        int orderStatus = orderInfo.getStatus();
        JSONObject extra = JSON.parseObject(orderInfo.getExtra());
        int packType = extra.getIntValue("pack_type");
        if (orderStatus == WechatPayStatusEnum.WECHAT_PAY_STATUS_MAKE.getType()) {
            String orgId = orderInfo.getPayerOrgId();
            ServiceResult<OrganizationDTO> organizationResult = organizationService.selectByPrimaryKey(orgId);
            OrganizationDTO org = organizationResult.getData();

            PackageDTO oldPack = packageGrpcService.getById(org.getFormalPackageId());
            if (Objects.isNull(oldPack) || StringUtils.isBlank(oldPack.getName())) {
                return ServiceResult.fail(ResourceErrorCodeEnum.NOT_FOUND, "获取套餐失败 id:" + org.getFormalPackageId());
            }
            PackageDTO nowPack = packageGrpcService.getByType(packType);
            if (Objects.isNull(nowPack) || StringUtils.isBlank(nowPack.getName())) {
                return ServiceResult.fail(ResourceErrorCodeEnum.NOT_FOUND, "获取套餐失败 type:" + packType);
            }

            // 获取系统管理员角色id
            UserRoleDTO userRoleDTO = new UserRoleDTO();
            userRoleDTO.setOrgId(orgId);
            userRoleDTO.setName(RolePermsEnum.ADMIN.getName());
            ServiceResult<String> superRole = roleService.getAdminRole(orgId);
            if (StringUtils.isBlank(superRole.getData())) {
                return ServiceResult.fail(ResourceErrorCodeEnum.NOT_FOUND, "获取系统管理员角色id失败");
            }

            // 获取系统管理员角色的用户
            List<String> userIds = userUserRoleService.listByRoleIdList(Collections.singletonList(superRole.getData()));
            if (CollectionUtils.isEmpty(userIds)) {
                return ServiceResult.fail(ResourceErrorCodeEnum.NOT_FOUND, "获取系统管理员角色的用户失败");
            }
            ServiceResult<List<UserDO>> result = userService.listByIds(null, null, userIds, null);
            List<UserDO> userDOS = result.getData();
            if (CollectionUtils.isEmpty(userDOS)) {
                return ServiceResult.fail(ResourceErrorCodeEnum.NOT_FOUND, "系统管理员用户不存在");
            }

            List<String> toEmails = getOmOrderEmails(org.getInnerFlag());

            // 套餐升级给销售发送邮件
            String subject = String.format("【待确认】%s租户购买%s版本通知", org.getName(), nowPack.getName());
            String packageEmailPrefix = "";
            if (settingProperties.getAppEnv().equals("production")) {
                packageEmailPrefix = "https://xm-company.idiaoyan.cn";
            } else {
                packageEmailPrefix = settingProperties.getServerProtocol() + "://www." + settingProperties.getXmServerHost();
            }
            String orgUrl = packageEmailPrefix + "/company/order/account";
            String fileName = EmailTemplateEnum.PACKAGE_PAY_NOTIFY_TEMPLATE.getFileName();
            HashMap<String, Object> map = new HashMap<>();
            map.put("org_name", org.getName());
            map.put("old_pack_name", oldPack.getName());
            map.put("now_pack_name", nowPack.getName());
            map.put("duration", extra.getIntValue("duration"));
            map.put("price", orderInfo.getTotalAmount());
            map.put("pay_method", PaymentMethodEnum.getByType(orderInfo.getPayMethod()).getDesc());
            map.put("order_id", orderId);
            map.put("org_url", orgUrl);
            map.put("org_code", org.getCode());
            map.put("org_mobile", userDOS.get(0).getPhone());
            map.put("org_email", userDOS.get(0).getEmail());
            map.put("notify_title", subject);
            map.put("org_id", org.getOrgId());
            userAsyncUtil.emailSendAndNotifyOm(toEmails.toArray(new String[toEmails.size()]), null, subject, fileName, map);

            // 短信提醒
            HashMap<String, Object> hashMap = new HashMap<>();
            hashMap.put("pack_name", nowPack.getName());
            String smsContent = StringFormatUtil.format(SmsConstant.PACKAGE_PAY_SUCCESS_SMS_TMPL, hashMap);
            log.info("[USER]对公转账，sms发送，smsContent={}", smsContent);
            Boolean status = userSmsService.sendSms(org.getAdminPhone(), smsContent);

            // 发送MQ
            if (StringUtils.isNotBlank(settingProperties.getAppName())) {
                SmsMessage smsMessage = new SmsMessage();
                smsMessage.setContent(smsContent)
                        .setName("版本购买-对公转账-付款回执")
                        .setOrgId(orgId)
                        .setReceiver(org.getAdminPhone())
                        .setSender("")
                        .setType(NotifyTypeEnum.MOBILE.getType())
                        .setStatus(Boolean.TRUE.equals(status) ? NotifyStatusEnum.IS_SEND.getType() :
                                NotifyStatusEnum.SEND_FAILED.getType())
                        .setSendTime(new SimpleDateFormat(DateUtil.NORM_DATETIME_PATTERN).format(DataBaseUtil.getDate()))
                        .setParams(nowPack.getName())
                        .setSmsChannel(NotifySmsChannelEnum.YIMEI.getType());
                //userMessageSender.publishOmSmsSyc(smsMessage);
            }

            // 线下支付订单, 用户点击已完成支付 调用企业钱包grpc
            String offlinePay = userPaymentGrpcService.confirmOfflinePay(orderId);
            if (Objects.isNull(offlinePay)) {
                return ServiceResult.fail(ResourceErrorCodeEnum.NO_DATA, String.format("线下支付订单, 用户点击已完成支付请求失败：orderNo:{%s}", orderId));
            }
        }
        return ServiceResult.success(orderId);
    }

    @Override
    public ServiceResult<Object> packWechatMackOrder(PackWeChatOrderDTO orderDTO) {
        ServiceResult<UserDTO> userResult = userService.selectById(orderDTO.getUserId());
        UserDTO userDTO = userResult.getData();

        ServiceResult<OrganizationDTO> orgResult = organizationService.selectByPrimaryKey(orderDTO.getOrgId());
        OrganizationDTO organizationDTO = orgResult.getData();
        if (Objects.isNull(organizationDTO)) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "org_code is not exists");
        }

        if (organizationDTO.getSource().equals(OrgSourceEnum.OPENPLATFORM.getType())) {
            return ServiceResult.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "请联系合作伙伴");
        }

        PackageDTO packageDTO = packageGrpcService.getByType(orderDTO.getPackType());
        if (Objects.isNull(packageDTO) || (!orderDTO.getPackType().equals(PackageTypeEnum.MAJOR.getType()) && !orderDTO.getPackType().equals(PackageTypeEnum.SENIOR.getType()))) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "package is not exists");
        }

        // 封装请求企业钱包的参数
        WalletOrderDTO walletOrderDTO = new WalletOrderDTO();
        walletOrderDTO.setWalletId(organizationDTO.getCorpWallet());
        walletOrderDTO.setType(OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType());
        walletOrderDTO.setSubject("倍市得版本购买");
        walletOrderDTO.setDescription("版本购买-" + PackageTypeEnum.getByType(orderDTO.getPackType()).getDesc());
        walletOrderDTO.setPayerUserId(orderDTO.getUserId());
        walletOrderDTO.setPayerOrgId(organizationDTO.getOrgId());
        walletOrderDTO.setPayerOrgCode(organizationDTO.getCode());
        walletOrderDTO.setPayerOrgName(organizationDTO.getName());
        walletOrderDTO.setPayerUserName(userDTO.getUserName());
        walletOrderDTO.setTotalAmount(packageDTO.getPrice() * orderDTO.getDuration());
        JSONObject extraJson = new JSONObject();
        extraJson.put("pack_type", orderDTO.getPackType());
        extraJson.put("duration", orderDTO.getDuration());
        walletOrderDTO.setExtra(extraJson.toJSONString());
        // 处理订单，根据是否有session_id 决定走小程序订单还是pc 端订单
        if (StringUtils.isNotBlank(orderDTO.getSessionId())) {
            ServiceResult<WeChatOrderDTO> result = dealOrderMiniProgram(walletOrderDTO, orderDTO.getSessionId());
            if (result.isSuccess()) {
                return ServiceResult.success(result.getData());
            }
            return ServiceResult.fail(result.getErrorData(), result.getMsg());
        }
        ServiceResult<OnlineOrderDTO> onlineOrderResult = dealOrderPc(walletOrderDTO);
        if (onlineOrderResult.isSuccess()) {
            return ServiceResult.success(onlineOrderResult.getData());
        }
        return ServiceResult.fail(onlineOrderResult.getErrorData(), onlineOrderResult.getMsg());
    }


    public ServiceResult<WeChatOrderDTO> dealOrderMiniProgram(WalletOrderDTO orderDTO, String sessionId) {
        if (StringUtils.isBlank(sessionId)) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_LOST, "session_id lost");
        }

        // 获取缓存wx_mini_session
        UserWxDataCacheDTO wxMiniSession = userWechatGrpcService.getWxCacheDataBySessionId(sessionId, UserOutterCacheKeyConstant.WX_MINI_SESSION_PREFIX);
        if (Objects.isNull(wxMiniSession)) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_LOST, String.format("session_id %s lost", sessionId));
        }

        if (StringUtils.isBlank(wxMiniSession.getOpenid())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_LOST, "openid not found");
        }
        MiniProgramOrderDTO miniProgramOrderDTO = new MiniProgramOrderDTO();
        miniProgramOrderDTO.setOrder(orderDTO);
        miniProgramOrderDTO.setOpenid(wxMiniSession.getOpenid());
        WeChatOrderDTO miniProgramOrder = userPaymentGrpcService.createMiniProgramOrder(miniProgramOrderDTO);
        // 轮训订单 apps_mysql/user/user_handlers.py:139
        packageOrderUpgradeTask(miniProgramOrder.getOrderId());
        return ServiceResult.success(miniProgramOrder);

    }

    private ServiceResult<OnlineOrderDTO> dealOrderPc(WalletOrderDTO orderDTO) {
        // 创建在线支付订单
        OnlineOrderDTO onlineOrder = userPaymentGrpcService.createOnlineOrder(orderDTO);
        // 轮训订单 apps_mysql/user/user_handlers.py:139
        packageOrderUpgradeTask(onlineOrder.getOrderNo());
        return ServiceResult.success(onlineOrder);
    }


    /**
     * 套餐订单轮询
     *
     * @param orderNo
     * @return void
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/07/12 16:56
     */
    private void packageOrderUpgradeTask(String orderNo) {
        if (log.isInfoEnabled()) {
            log.info("轮训订单开始");
        }
        OrderDTO orderDTO = userPaymentGrpcService.getOrderStatus2(orderNo);
        // 倍市得版本购买
        if (!orderDTO.getType().equals(OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType())) {
            return;
        }
        // 已支付
        if (orderDTO.getStatus().equals(WechatPayStatusEnum.WECHAT_PAY_STATUS_PAID.getType())) {
            // 升级套餐
            if (log.isInfoEnabled()) {
                log.info("轮训订单-套餐升级执行");
            }
            packageGrpcService.upgradePackage(orderNo);
        }
        // WECHAT_PAY_STATUS_MAKE
        if (orderDTO.getStatus().equals(WechatPayStatusEnum.WECHAT_PAY_STATUS_MAKE.getType())) {
            executor.schedule(() -> packageOrderUpgradeTask(orderNo), 30, TimeUnit.SECONDS);
        }
    }


    @Override
    public ServiceResult<PackOrderStatusDTO> getPackOrderStatus(String orderNo) {
        OrderDTO orderDTO = userPaymentGrpcService.getOrderStatus2(orderNo);
        // 判断订单是否是倍市得购买或是微信支付的
        if (!orderDTO.getType().equals(OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType()) ||
                !orderDTO.getPayMethod().equals(PaymentMethodEnum.PAYMENT_METHOD_WECHAT.getType())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, String.format("order_id[%s] is error", orderNo));
        }
        if (orderDTO.getStatus().equals(WechatPayStatusEnum.WECHAT_PAY_STATUS_PAID.getType())) {
            // 升级套餐
            packageGrpcService.upgradePackage(orderNo);
        }
        PackOrderStatusDTO statusDTO = new PackOrderStatusDTO();
        statusDTO.setOrderStatus(orderDTO.getStatus());
        statusDTO.setOrderId(orderNo);
        return ServiceResult.success(statusDTO);
    }


    @Override
    public ServiceResult<Object> trialPackWechatMackOrder(WxMackOrderDTO orderDTO) {

        ServiceResult<OrganizationDTO> orgResult = organizationService.selectByPrimaryKey(orderDTO.getOrgId());
        if (!orgResult.isSuccess() || Objects.isNull(orgResult.getData())) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "org_code is not exists");
        }
        OrganizationDTO organizationDTO = orgResult.getData();
        if (organizationDTO.getSource().equals(OrgSourceEnum.OPENPLATFORM.getType())) {
            return ServiceResult.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "请联系合作伙伴");
        }
        UserDTO userDTO = userService.selectById(orderDTO.getUserId()).getData();
        PackageDTO packageDTO = packageGrpcService.getByNameAndType(CommonConstant.TRIAL_1111_PACK_NAME, orderDTO.getPackType());
        if (Objects.isNull(packageDTO)) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "package is not exists");
        }
        Date now = new Date();
        if (now.before(packageDTO.getDiscountBeginTime()) || now.after(packageDTO.getDiscountEndTime())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "活动已结束");
        }
        if (orderDTO.getPackDuration() != 1) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "duration invalid");
        }
        PackageDTO oldPackage = packageGrpcService.getById(organizationDTO.getFormalPackageId());

        if (oldPackage.getType().equals(PackageTypeEnum.SENIOR.getType())
                || oldPackage.getType().equals(PackageTypeEnum.FREE.getType())
                || oldPackage.getType().equals(PackageTypeEnum.FREE_TRIAL.getType())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "仅基础版，高级版参加活动");
        }

        // 封装请求企业钱包的参数
        WalletOrderDTO walletOrderDTO = new WalletOrderDTO();
        walletOrderDTO.setWalletId(organizationDTO.getCorpWallet());
        walletOrderDTO.setType(OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType());
        walletOrderDTO.setSubject("专业版试用资格限时抢");
        walletOrderDTO.setDescription("版本购买-" + PackageTypeEnum.getByType(orderDTO.getPackType()).getDesc() + "-试用");
        walletOrderDTO.setPayerUserId(orderDTO.getUserId());
        walletOrderDTO.setPayerOrgId(organizationDTO.getOrgId());
        walletOrderDTO.setPayerOrgCode(organizationDTO.getCode());
        walletOrderDTO.setPayerOrgName(organizationDTO.getName());
        walletOrderDTO.setPayerUserName(userDTO.getUserName());
        walletOrderDTO.setTotalAmount((packageDTO.getDiscountPrice() / 12) * orderDTO.getPackDuration());
        JSONObject extraJson = new JSONObject();
        extraJson.put("pack_type", orderDTO.getPackType());
        extraJson.put("duration", orderDTO.getPackDuration());
        extraJson.put("duration_unit", OrderExtraDurationEnum.ORDER_EXTRA_DURATION_MONTH.getType());
        extraJson.put("activity_code", CommonConstant.ORDER_BUY_TYPE_TRIAL);
        walletOrderDTO.setExtra(extraJson.toJSONString());
        // 处理订单，根据是否有session_id 决定走小程序订单还是pc 端订单
        if (StringUtils.isNotBlank(orderDTO.getSessionId())) {
            ServiceResult<WeChatOrderDTO> result = dealOrderMiniProgram(walletOrderDTO, orderDTO.getSessionId());
            if (result.isSuccess()) {
                return ServiceResult.success(result.getData());
            }
            return ServiceResult.fail(result.getErrorData(), result.getMsg());
        }
        ServiceResult<OnlineOrderDTO> onlineOrderResult = dealOrderPc(walletOrderDTO);
        if (onlineOrderResult.isSuccess()) {
            return ServiceResult.success(onlineOrderResult.getData());
        }
        return ServiceResult.fail(onlineOrderResult.getErrorData(), onlineOrderResult.getMsg());
    }


    @Override
    public ServiceResult<Object> discountPackWechatMackOrder(WxMackOrderDTO orderDTO) {
        ServiceResult<OrganizationDTO> orgResult = organizationService.selectByPrimaryKey(orderDTO.getOrgId());
        if (!orgResult.isSuccess() || Objects.isNull(orgResult.getData())) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "org_code is not exists");
        }
        OrganizationDTO organizationDTO = orgResult.getData();
        if (organizationDTO.getSource().equals(OrgSourceEnum.OPENPLATFORM.getType())) {
            return ServiceResult.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "请联系合作伙伴");
        }
        // check_params ^
        UserDTO userDTO = userService.selectById(orderDTO.getUserId()).getData();
        PackageDTO packageDTO = packageGrpcService.getByNameAndType(CommonConstant.TRIAL_1111_PACK_NAME, orderDTO.getPackType());
        if (Objects.isNull(packageDTO)) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "package is not exists");
        }
        Date now = new Date();
        if (now.before(packageDTO.getDiscountBeginTime()) || now.after(packageDTO.getDiscountEndTime())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "活动已结束");
        }
        if (orderDTO.getPackDuration() != 1) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "duration invalid");
        }
        PackageDTO oldPackage = packageGrpcService.getById(organizationDTO.getFormalPackageId());

        if (oldPackage.getType().equals(PackageTypeEnum.FREE.getType())
                || oldPackage.getType().equals(PackageTypeEnum.FREE_TRIAL.getType())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "仅基础版参加活动");
        }

        // 封装请求企业钱包的参数
        WalletOrderDTO walletOrderDTO = new WalletOrderDTO();
        walletOrderDTO.setWalletId(organizationDTO.getCorpWallet());
        walletOrderDTO.setType(OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType());
        walletOrderDTO.setSubject("高级版，专业版四折购买");
        walletOrderDTO.setDescription("版本购买-" + PackageTypeEnum.getByType(orderDTO.getPackType()).getDesc() + "-四折购买");
        walletOrderDTO.setPayerUserId(orderDTO.getUserId());
        walletOrderDTO.setPayerOrgId(organizationDTO.getOrgId());
        walletOrderDTO.setPayerOrgCode(organizationDTO.getCode());
        walletOrderDTO.setPayerOrgName(organizationDTO.getName());
        walletOrderDTO.setPayerUserName(userDTO.getUserName());
        walletOrderDTO.setTotalAmount(packageDTO.getDiscountPrice() * orderDTO.getPackDuration());
        JSONObject extraJson = new JSONObject();
        extraJson.put("pack_type", orderDTO.getPackType());
        extraJson.put("duration", orderDTO.getPackDuration());
        extraJson.put("duration_unit", OrderExtraDurationEnum.ORDER_EXTRA_DURATION_YEAR.getType());
        extraJson.put("activity_code", CommonConstant.ORDER_BUY_TYPE_DISCOUNT);
        walletOrderDTO.setExtra(extraJson.toJSONString());
        // 处理订单，根据是否有session_id 决定走小程序订单还是pc 端订单
        if (StringUtils.isNotBlank(orderDTO.getSessionId())) {
            ServiceResult<WeChatOrderDTO> result = dealOrderMiniProgram(walletOrderDTO, orderDTO.getSessionId());
            if (result.isSuccess()) {
                return ServiceResult.success(result.getData());
            }
            return ServiceResult.fail(result.getErrorData(), result.getMsg());
        }
        ServiceResult<OnlineOrderDTO> onlineOrderResult = dealOrderPc(walletOrderDTO);
        if (onlineOrderResult.isSuccess()) {
            return ServiceResult.success(onlineOrderResult.getData());
        }
        return ServiceResult.fail(onlineOrderResult.getErrorData(), onlineOrderResult.getMsg());
    }


    @Override
    public ServiceResult<Object> discountOfflineMakeOrder(WxMackOrderDTO orderDTO) {

        ServiceResult<OrganizationDTO> orgResult = organizationService.selectByPrimaryKey(orderDTO.getOrgId());
        if (!orgResult.isSuccess() || Objects.isNull(orgResult.getData())) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "org_code is not exists");
        }
        OrganizationDTO organizationDTO = orgResult.getData();
        if (organizationDTO.getSource().equals(OrgSourceEnum.OPENPLATFORM.getType())) {
            return ServiceResult.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "请联系合作伙伴");
        }
        // check_params ^
        UserDTO userDTO = userService.selectById(orderDTO.getUserId()).getData();
        PackageDTO packageDTO = packageGrpcService.getByNameAndType(CommonConstant.TRIAL_1111_PACK_NAME, orderDTO.getPackType());
        if (Objects.isNull(packageDTO)) {
            return ServiceResult.fail(AuthErrorCodeEnum.ORG_NOT_EXISTS, "package is not exists");
        }
        Date now = new Date();
        if (now.before(packageDTO.getDiscountBeginTime()) || now.after(packageDTO.getDiscountEndTime())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "活动已结束");
        }
        if (orderDTO.getPackDuration() != 1) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "duration invalid");
        }
        PackageDTO oldPackage = packageGrpcService.getById(organizationDTO.getFormalPackageId());

        if (oldPackage.getType().equals(PackageTypeEnum.FREE.getType())
                || oldPackage.getType().equals(PackageTypeEnum.FREE_TRIAL.getType())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_FORMAT, "仅基础版参加活动");
        }

        // 封装请求企业钱包的参数
        WalletOrderDTO walletOrderDTO = new WalletOrderDTO();
        walletOrderDTO.setWalletId(organizationDTO.getCorpWallet());
        walletOrderDTO.setType(OrderTypeEnum.ORDER_TYPE_BESTCEM_PURCHASE.getType());
        walletOrderDTO.setSubject("高级版，专业版四折购买");
        walletOrderDTO.setDescription("版本购买-" + PackageTypeEnum.getByType(orderDTO.getPackType()).getDesc() + "-四折购买-线下支付");
        walletOrderDTO.setPayerUserId(orderDTO.getUserId());
        walletOrderDTO.setPayerOrgId(organizationDTO.getOrgId());
        walletOrderDTO.setPayerOrgCode(organizationDTO.getCode());
        walletOrderDTO.setPayerOrgName(organizationDTO.getName());
        walletOrderDTO.setPayerUserName(userDTO.getUserName());
        walletOrderDTO.setTotalAmount(packageDTO.getDiscountPrice() * orderDTO.getPackDuration());
        JSONObject extraJson = new JSONObject();
        extraJson.put("pack_type", orderDTO.getPackType());
        extraJson.put("duration", orderDTO.getPackDuration());
        extraJson.put("duration_unit", OrderExtraDurationEnum.ORDER_EXTRA_DURATION_YEAR.getType());
        extraJson.put("activity_code", CommonConstant.ORDER_BUY_TYPE_DISCOUNT);
        walletOrderDTO.setExtra(extraJson.toJSONString());
        // 处理订单，根据是否有session_id 决定走小程序订单还是pc 端订单
        if (StringUtils.isNotBlank(orderDTO.getSessionId())) {
            ServiceResult<WeChatOrderDTO> result = dealOrderMiniProgram(walletOrderDTO, orderDTO.getSessionId());
            if (result.isSuccess()) {
                return ServiceResult.success(result.getData());
            }
            return ServiceResult.fail(result.getErrorData(), result.getMsg());
        }
        ServiceResult<OnlineOrderDTO> onlineOrderResult = dealOrderPc(walletOrderDTO);
        if (onlineOrderResult.isSuccess()) {
            return ServiceResult.success(onlineOrderResult.getData());
        }
        return ServiceResult.fail(onlineOrderResult.getErrorData(), onlineOrderResult.getMsg());
    }

    /**
     * 获取OM
     *
     * @param innerType
     * @return
     */
    private List<String> getOmOrderEmails(int innerType) {
        return omUserGrpcService.getOmEmailConfig(OmEmailType.ORDER.getType(), innerType);
    }
}
